using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Transactions;
using T.FAS.Runtime.Base.Dao;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.ScheduleJob.SPI;
using T.ServiceComponent.DAC.Service;
using T.ServiceComponent.DataAccessEx.Core;
using IsolationLevel = System.Transactions.IsolationLevel;

namespace T.FAS.Runtime.ScheduleJob.Dao
{
    public class ScheduleJobSubscriptionDao : DaoService<ScheduleJobSubscription>
    {
        public override string TableName => "FAS_ScheduleJobSubscription";
        public override string IDColumnName => "ID";

        public override List<string> ExceptColumnName
            => DaoUtil.GetExceptionColumn<ScheduleJobSubscription>(
                new List<string>
                {
                }
            );
        public ScheduleJobSubscriptionDao() : base()
        {
            DBName = "TFAS";
        }
        public override ScheduleJobSubscription ConvertToObject(Dictionary<string, PropertyInfo> columns, DataRow row)
        {
            if (columns.ContainsKey("TriggerType"))
                columns.Remove("TriggerType");
            if (columns.ContainsKey("ComplexTriggerCondition"))
            if (columns.ContainsKey("IsBasic"))
                columns.Remove("IsBasic");
            if (columns.ContainsKey("ReturnType"))
                columns.Remove("ReturnType");
            if (columns.ContainsKey("SourceType"))
                columns.Remove("SourceType");
            var data = base.ConvertToObject(columns,row);

            data.TriggerType = (TriggerType)Enum.Parse(typeof(TriggerType),Convert.ToString(row["TriggerType"]));
            data.IsBasic = Convert.ToInt32(row["IsBasic"]).Equals(1) ? true : false;
            data.ReturnType = (DataType)Enum.Parse(typeof(DataType), Convert.ToString(row["ReturnType"]));
            data.SourceType = (SubscriptionSourceType)Enum.Parse(typeof(DataType), Convert.ToString(row["SourceType"]));
            return data;
        }
        public override Dictionary<string, object> GetDataMapping(ScheduleJobSubscription data)
        {
            var mapping = base.GetDataMapping(data);
            mapping.Remove("TriggerType");
            mapping.Add("TriggerType", (int)data.TriggerType);
            mapping.Remove("IsBasic");
            mapping.Add("IsBasic", data.IsBasic?1:0);
            mapping.Remove("ReturnType");
            mapping.Add("ReturnType", (int)data.ReturnType);
            mapping.Remove("SourceType");
            mapping.Add("SourceType", (int)data.SourceType);
            return mapping;
        }
        public override Dictionary<string, PropertyInfo> GetColumns()
        {
            return base.GetColumns();
        }
        private ScheduleJobSubscriptionNoticeSetDao noticeDao => new ScheduleJobSubscriptionNoticeSetDao();
        private SubscriptionNoticeDefinitionDao noticedefineDao => new SubscriptionNoticeDefinitionDao();
        private ScheduleJobSubscriptionFrequencyDao frequencyDao => new ScheduleJobSubscriptionFrequencyDao();

        public void AddScheduleJobSubscription(ScheduleJobSubscription data)
        {
            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted }))
                {
                    base.Add(new List<object>() { data});
                    if (data.NoticeSets != null)
                    {
                        data.NoticeSets.ForEach(x =>
                        {
                            if (string.IsNullOrEmpty(x.ID))
                                x.ID = Guid.NewGuid().ToString();
                            x.ScheduleJobSubscriptionID = data.ID;
                        });
                        noticeDao.Add(data.NoticeSets);
                        if (data.NoticeSets != null)
                        {
                            data.NoticeSets.ForEach(n =>
                            {
                                if (!string.IsNullOrEmpty(n.SubscriptionNoticeDefinitionID))
                                {
                                    var tmp = noticedefineDao.Get(n.SubscriptionNoticeDefinitionID);
                                    if (tmp != null)
                                        n.SubscriptionNoticeDefinition = tmp as SubscriptionNoticeDefinition;
                                }
                            });
                        }
                    }
                    if (data.ExecuteFrequency != null)
                    {
                        data.ExecuteFrequency.ScheduleJobSubscriptionID = data.ID;
                        frequencyDao.AddScheduleJobSubscriptionFrequency(data.ExecuteFrequency);
                    }
                    scope.Complete();
                }
            }
            catch (Exception e)
            {
                throw new Exception(string.Format(CommonStringClassDao.ScheduleJobSubscriptionDao_AddScheduleJobSubscription,data.BusinessType),e);
            }
        }
        public ScheduleJobSubscription GetScheduleJobSubscriptionById(string subscriptionId)
        {
            var subscriptionData = base.Get(subscriptionId);
            var subscription = subscriptionData as ScheduleJobSubscription;
            if (subscription == null)
            {
                return null;
            }
            subscription.ExecuteFrequency = frequencyDao.GetScheduleJobSubscriptionFrequencyBySubId(subscriptionId);
            subscription.NoticeSets = noticeDao.GetScheduleJobSubscriptionNoticeSetBySubId(subscriptionId);
            return subscription;
        }

        public List<ScheduleJobSubscription> GetScheduleJobSubscriptionsByFilter(UserDefineQueryFilter filter)
        {
            var list = new List<ScheduleJobSubscription>();
            string queryFilter = " 1=1 ";
            if (filter != null && filter.Count > 0)
            {
                if (filter.ContainsKey("UserID"))
                {
                    queryFilter += $" and OwnerID = '{filter.GetStringData("UserID")}'";
                }
                if (filter.ContainsKey("BusinessType"))
                {
                    queryFilter += $" and BusinessType='{filter.GetStringData("BusinessType")}'";
                }
            }
            var result = base.GetObjectsByFilter(queryFilter);
            if (result != null && result.Count > 0)
            {
                result.ForEach(x => list.Add(x as ScheduleJobSubscription));
            }
            return list;
        }
        public void DeleteScheduleJobSubscription(string subscriptionId)
        {
            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted }))
                {
                    base.Delete(new List<string>() { subscriptionId });
                    noticeDao.DeleteScheduleJobSubscriptionNoticeSet(subscriptionId);
                    frequencyDao.DeleteScheduleJobSubscriptionFrequency(subscriptionId);
                    scope.Complete();
                }
            }
            catch (Exception e)
            {
                throw new Exception(string.Format(CommonStringClassDao.ScheduleJobSubscriptionDao_DeleteScheduleJobSubscription,subscriptionId), e);
            }
        }
    }
}
